package com.aiyige.base.api.httpinterceptor;

import android.util.Base64;

import com.aiyige.BuildConfig;
import com.aiyige.MyApp;
import com.aiyige.R;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.api.ResponseCode;
import com.aiyige.base.api.TokenManager;
import com.aiyige.jpush.TagAliasOperatorHelper;
import com.aiyige.model.TokenResponse;
import com.aiyige.model.User;
import com.aiyige.model.response.BaseResponse;
import com.aiyige.page.my.message.util.MessageUtil;
import com.aiyige.utils.AccountUtil;
import com.aiyige.utils.ErrorUtil;
import com.aiyige.utils.RetrofitUtil;
import com.aiyige.utils.StringUtils;
import com.aiyige.utils.exception.NeedLoginException;
import com.alibaba.android.arouter.launcher.ARouter;
import com.alibaba.fastjson.JSON;

import java.io.IOException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class AuthIntercetpor implements Interceptor {
    public static final int REFRESH_TOKEN_STATE_REFRESHING = 1;
    public static final int REFRESH_TOKEN_STATE_NEED_REFRESH = 2;
    public static final int REFRESH_TOKEN_STATE_REFRESH_SUCCESS = 3;
    public static final int REFRESH_TOKEN_STATE_REFRESH_FAILED = 4;
    Lock guestMutex;
    Lock userMutex;
    String clientInfo = "";
    volatile int refreshTokenState;

    public AuthIntercetpor() {
        guestMutex = new ReentrantLock();
        userMutex = new ReentrantLock();
        try {
            clientInfo = Base64.encodeToString((BuildConfig.AIYIGE_CLIENT_ID + ":" + BuildConfig.AIYIGE_CLIENT_SECRET).getBytes("UTF-8"), Base64.NO_WRAP | Base64.URL_SAFE);
        } catch (Exception e) {
            clientInfo = "";
        }
        refreshTokenState = REFRESH_TOKEN_STATE_NEED_REFRESH;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
//        if (!AccountUtil.isGuestLogin()) {
//            guestMutex.lock();
//            if (!AccountUtil.isGuestLogin()) {
//                try {
//                    retrofit2.Response<ResponseBody> response = TokenManager.getService().getGuestToken("Basic "+clientInfo, "client_credentials").execute();
//                    if (response.code() != ResponseCode.OK) {
//                        throw new IOException(ErrorUtil.extractMessageFromErrorResponse(response));
//                    }
//                    String json = RetrofitUtil.getResponseBodyAsString(response);
//                    TokenResponse tokenResponse = JSON.parseObject(json, TokenResponse.class);
//                    User user = new User();
//                    user.getAccessToken().setToken_type(User.TOKEN_TYPE_GUEST);
//                    user.getAccessToken().setAccess_token(BuildConfig.GUEST_ACCESS_TOKEN);
//                    AccountUtil.updateCurrentUser(user);
//                } catch (Exception e) {
//                    guestMutex.unlock();
//                    throw new IOException(e.getMessage());
//                }
//            }
//            guestMutex.unlock();
//        }
        Response response = chain.proceed(request);

        if (response.code() == ResponseCode.UNAUTHORIZED) {
            try {
                String json = response.body().string();
                BaseResponse baseResponse = JSON.parseObject(json, BaseResponse.class);
                switch (baseResponse.getCode()) {
                    case ResponseCode.TOKEN_EXPIRED: {
                        if (refreshTokenState != REFRESH_TOKEN_STATE_REFRESHING) {
                            refreshTokenState = REFRESH_TOKEN_STATE_NEED_REFRESH;
                        }
                        userMutex.lock();
                        if (refreshTokenState == REFRESH_TOKEN_STATE_NEED_REFRESH || refreshTokenState == REFRESH_TOKEN_STATE_REFRESH_FAILED) {
                            refreshTokenState = REFRESH_TOKEN_STATE_REFRESHING;
                            try {
                                retrofit2.Response<ResponseBody> refreshTokenResp = TokenManager.getService().refreshToken("Basic " + clientInfo, "refresh_token", AccountUtil.getCurrentUser().getAccessToken().getRefresh_token()).execute();
                                if (refreshTokenResp.code() == ResponseCode.UNAUTHORIZED) {
                                    AccountUtil.clearCurrentUser();
                                    MessageUtil.clearNewMessage();
                                    TagAliasOperatorHelper.getInstance().cleanLoginTagAndAlias(MyApp.getAppContext());
                                    ARouter.getInstance().build(ARouterConfig.LoginPage).navigation();
                                    throw new NeedLoginException(StringUtils.getString(R.string.please_login));
                                } else if (refreshTokenResp.code() != ResponseCode.OK) {
                                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(refreshTokenResp));
                                }
                                String refreshTokenJson = RetrofitUtil.getResponseBodyAsString(refreshTokenResp);
                                TokenResponse tokenResponse = JSON.parseObject(refreshTokenJson, TokenResponse.class);
                                User user = AccountUtil.getCurrentUser();
                                user.getAccessToken().setAccess_token(tokenResponse.getAccess_token());
                                user.getAccessToken().setRefresh_token(tokenResponse.getRefresh_token());
                                user.getAccessToken().setToken_type(tokenResponse.getToken_type());
                                user.getAccessToken().setExpires_in(tokenResponse.getExpires_in());
                                AccountUtil.updateCurrentUser(user);
                                refreshTokenState = REFRESH_TOKEN_STATE_REFRESH_SUCCESS;
                                response = chain.proceed(request);
                                userMutex.unlock();
                                return response;
                            } catch (Exception e) {
                                refreshTokenState = REFRESH_TOKEN_STATE_REFRESH_FAILED;
                                userMutex.unlock();
                                throw new IOException(e.getMessage());
                            }
                        } else {
                            userMutex.unlock();
                            return chain.proceed(request);
                        }
                    }
                    case ResponseCode.TOKEN_ERROR:
                    case ResponseCode.NOT_LOGIN:
                    case ResponseCode.LOGIN_FIRST: {
                        AccountUtil.clearCurrentUser();
                        MessageUtil.clearNewMessage();
                        TagAliasOperatorHelper.getInstance().cleanLoginTagAndAlias(MyApp.getAppContext());
                        ARouter.getInstance().build(ARouterConfig.LoginPage).navigation();
                        throw new Exception(StringUtils.getString(R.string.please_login));
                    }
                    default: {
                        return response.newBuilder()
                                .body(ResponseBody.create(MediaType.parse("text/plain"), json))
                                .build();
                    }
                }
            } catch (Exception e) {
                throw new IOException(e.getMessage());
            }
        } else {
            return response;
        }
    }
}

